PCB_NAME           := imx6ull-alpha-emmc
DTB_NAME           := imx6ull-alpha-emmc
DTB_PLUG_IN_NAME   := imx6ull-alpha-plugin

ARCH               ?= arm
CURRENT_PATH       := $(shell pwd)
DTC                ?= $(CURRENT_PATH)/../../../kernel/scripts/dtc/dtc

INCDIRS 		   := ./ \
					  $(CURRENT_PATH)/../../../kernel/dts_common \
					  $(CURRENT_PATH)/../../../kernel/include \
					  ./${PCB_NAME}

SRCDIRS			   := ./

COMPILE_OPT_HEADER := $(patsubst %, -I%, $(INCDIRS))

DTC_CC_FLAGS       = -E -Wp,-MD,$(<D)/.$(@F:.dtb=).dtb.predts.tmp.d
DTC_CC_FLAGS      += -nostdinc
DTC_CC_FLAGS      += $(COMPILE_OPT_HEADER)
DTC_CC_FLAGS      += -undef -D__DTS__ -x assembler-with-cpp

DTC_FLAGS          = $(shell echo "-W no-unique_unit_address -W no-unit_address_format -W no-unit_address_vs_reg")

# kernel相关目录
# ---------------------------------------------------------------------------
# 选择可执行文件运行的平台
ifeq ($(ARCH), arm)
  KERNELDIR            ?= ~/7Linux/imx6ull-kernel
  CROSS_COMPILE_PREFIX ?= arm-linux-gnueabihf-
else
  KERNELDIR            ?= /lib/modules/$(shell uname -r)/build
  CROSS_COMPILE_PREFIX ?=
endif

CC                   := $(CROSS_COMPILE_PREFIX)gcc
LD                   := $(CROSS_COMPILE_PREFIX)ld

# 设备树文件源码目录及设备树名称
DTS_FILES                 := $(DTB_NAME).dts
DTS_FILES                 += $(DTB_NAME).dtsi

DT_IN_LINUX_DIR           := $(KERNELDIR)/arch/arm/boot/dts
DTB_IN_LINUX_FILE         := $(DT_IN_LINUX_DIR)/$(DTB_NAME).dtb

DT_IN_PROJECT_DIR         := $(CURRENT_PATH)/$(PCB_NAME)
DTB_IN_PROJECT_FILE       := $(DT_IN_PROJECT_DIR)/$(DTB_NAME).dtb

# 服务器等的目录定义
# ---------------------------------------------------------------------------
TFTP_SERVER       ?= ~/3tftp
NFS_SERVER        ?= ~/4nfs

TFTP_DIR          ?= $(TFTP_SERVER)
ROOTFS_ROOT_DIR   ?= $(NFS_SERVER)/imx6ull_rootfs
# ROOTFS_MODULE_DIR 可以被上层makefile中导出的同名变量覆盖
#ROOTFS_MODULE_DIR ?= $(ROOTFS_ROOT_DIR)/lib/modules/4.19.71-00007-g51f3cd8ec-dirty
ROOTFS_MODULE_DIR ?= $(ROOTFS_ROOT_DIR)/drivers_demo
# Beautify output
# ---------------------------------------------------------------------------
#
# Normally, we echo the whole command before executing it. By making
# that echo $($(quiet)$(cmd)), we now have the possibility to set
# $(quiet) to choose other forms of output instead, e.g.
#
#         quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
#         cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
#
# If $(quiet) is empty, the whole command will be printed.
# If it is set to "quiet_", only the short version will be printed.
# If it is set to "silent_", nothing will be printed at all, since
# the variable $(silent_cmd_cc_o_c) doesn't exist.
#
# A simple variant is to prefix commands with $(Q) - that's useful
# for commands that shall be hidden in non-verbose mode.
#
#	$(Q)ln $@ :<
#
# If KBUILD_VERBOSE equals 0 then the above command will be hidden.
# If KBUILD_VERBOSE equals 1 then the above command is displayed.
#
# To put more focus on warnings, be less verbose as default
# Use 'make V=1' to see the full commands

ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSE
  KBUILD_VERBOSE = 0
endif

ifeq ($(KBUILD_VERBOSE),1)
  quiet =
  Q =
else
  quiet=quiet_
  Q = @
endif

# If the user is running make -s (silent mode), suppress echoing of
# commands

ifneq ($(filter 4.%,$(MAKE_VERSION)),)	# make-4, make执行时会自动赋值
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
  quiet=silent_
endif
else					# make-3.8x
ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
  quiet=silent_
endif
endif

# cmd define
# ---------------------------------------------------------------------------
squote     := '
escsq       = $(subst $(squote),'\$(squote)',$1)
# echo command.
# Short version is used, if $(quiet) equals `quiet_', otherwise full one.
echo-cmd    = $(if $($(quiet)cmd_$(1)),\
				echo '  $(call escsq,$($(quiet)cmd_$(1)))';)

# printing commands
cmd 		= @$(echo-cmd) $(cmd_$(1))

# copy 命令的定义，一般会定义两个，带 quiet_ 前缀的和不带这个前缀的
# 为什么定义两个? 例如 通过 if_changed 函数来调用
# make V=1 ... 会打印 cmd_copy 的内容并且执行 cp $< $@ 命令
# make V=0 ... 会打印 quiet_cmd_copy 的内容并且执行 cp $< $@ 命令
quiet_cmd_copy = COPY    $@
      cmd_copy = cp $< $@

quiet_cmd_mkdir = MKDIR    $@
      cmd_mkdir = mkdir -p $@

quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN   $(wildcard $(rm-dirs)))
      cmd_rmdirs = rm -rf $(rm-dirs)

quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN   $(wildcard $(rm-files)))
      cmd_rmfiles = rm -f $(rm-files)

# $(@D) 目标的目录部分, $(@F) 目标的文件部分
# $(<D) 第一个依赖的目录部分, $(<F) 第一个依赖的文件部分
quiet_cmd_dep = DEP     $@
      cmd_dep = $(CC) $(DTC_CC_FLAGS) -o $(<D)/.$(@F:.dtb=).dtb.dts.tmp $<

quiet_cmd_dtc = DTC     $@
      cmd_dtc = $(DTC) -I dts -O dtb -o $(@) \
	  			-b 0 -p 10240 $(DTC_CFLAGS) \
				-d $(<D)/.$(@F:.dtb=).dtb.dtc.tmp.d \
				$(<D)/.$(@F:.dtb=).dtb.dts.tmp

# target
# ---------------------------------------------------------------------------
dt-dtb: ${PCB_NAME}/${PCB_NAME}.dtb

${PCB_NAME}/${PCB_NAME}.dtb: ${PCB_NAME}/${PCB_NAME}.dts
	$(call cmd,dep)
	$(call cmd,dtc)

kernel-dtb:
	@cd $(DT_IN_PROJECT_DIR) && cp -a $(DTS_FILES) $(DT_IN_LINUX_DIR)
	$(MAKE) ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C $(KERNELDIR) M=$(CURRENT_PATH) $(DTB_NAME).dtb -j4
	@cp -a $(DTB_IN_LINUX_FILE) $(DT_IN_PROJECT_DIR)

dtb-plug-in:
	$(DTC) -I dts -O dtb $(DTB_PLUG_IN_NAME).dts -o $(DTB_PLUG_IN_NAME).dtbo

dts:
	$(DTC) -I dtb -O dts -o imx6ull-alpha-emmc.dts $(DTB_NAME).dtb

install:
	@sudo cp -v $(DTB_IN_PROJECT_FILE) $(TFTP_DIR)
#	@sudo cp -v $(DTB_PLUG_IN_NAME).dtbo $(ROOTFS_MODULE_DIR)

cpy_dts:
	@cd $(DT_IN_LINUX_DIR) && cp -avf $(DTS_FILES) $(DT_IN_PROJECT_DIR)

# clean
# ---------------------------------------------------------------------------
# Files to ignore in find ... statements
# ---------------------------------------------------------------------------
export RCS_FIND_IGNORE := \( -name .svn -o    \
							 -name .git \) \
			  				 -prune -o
export RCS_TAR_IGNORE  := --exclude SCCS --exclude BitKeeper --exclude .svn \
			 			  --exclude CVS --exclude .pc --exclude .hg --exclude .git

# Directories & files removed with 'make clean'
CLEAN_DIRS     += 
CLEAN_FILES    += *.dtb *.dtbo $(DTB_IN_LINUX_FILE)

# clean - Delete most, but leave enough to build external modules
#
clean: rm-dirs  := $(CLEAN_DIRS)
clean: rm-files := $(CLEAN_FILES)

PHONY += clean

clean:
	$(call cmd,rmdirs)
	$(call cmd,rmfiles)
	@find $(RCS_FIND_IGNORE) \
		\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
		 -o -name '*.ko.*' -o -name '*.su' -o -name '.*.d' \
		 -o -name '.*.tmp' -o -name '.tmp_*.o.*' \
		 -o -name '*.dtb' -o -name '.${PCB_NAME}.*' \) \
		-type f -print | xargs rm -f

# PHONY 伪目标
# ---------------------------------------------------------------------------	
PHONY += FORCE
FORCE:

# Declare the contents of the .PHONY variable as phony.  We keep that
# information in a variable so we can use it in if_changed and friends.
.PHONY: $(PHONY)
